//C- -------------------------------------------------------------------
//C- Java DjVu (r) (v. 0.8)
//C- Copyright (c) 2004-2005 LizardTech, Inc.  All Rights Reserved.
//C- Java DjVu is protected by U.S. Pat. No.C- 6,058,214 and patents
//C- pending.
//C-
//C- This software is subject to, and may be distributed under, the
//C- GNU General Public License, Version 2. The license should have
//C- accompanied the software or you may obtain a copy of the license
//C- from the Free Software Foundation at http://www.fsf.org .
//C-
//C- The computer code originally released by LizardTech under this
//C- license and unmodified by other parties is deemed "the LIZARDTECH
//C- ORIGINAL CODE."  Subject to any third party intellectual property
//C- claims, LizardTech grants recipient a worldwide, royalty-free,
//C- non-exclusive license to make, use, sell, or otherwise dispose of
//C- the LIZARDTECH ORIGINAL CODE or of programs derived from the
//C- LIZARDTECH ORIGINAL CODE in compliance with the terms of the GNU
//C- General Public License.   This grant only confers the right to
//C- infringe patent claims underlying the LIZARDTECH ORIGINAL CODE to
//C- the extent such infringement is reasonably necessary to enable
//C- recipient to make, have made, practice, sell, or otherwise dispose
//C- of the LIZARDTECH ORIGINAL CODE (or portions thereof) and not to
//C- any greater extent that may be necessary to utilize further
//C- modifications or combinations.
//C-
//C- The LIZARDTECH ORIGINAL CODE is provided "AS IS" WITHOUT WARRANTY
//C- OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
//C- TO ANY WARRANTY OF NON-INFRINGEMENT, OR ANY IMPLIED WARRANTY OF
//C- MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
//C-
//C- In addition, as a special exception, LizardTech Inc. gives permission
//C- to link the code of this program with the proprietary Java
//C- implementation provided by Sun (or other vendors as well), and
//C- distribute linked combinations including the two. You must obey the
//C- GNU General Public License in all respects for all of the code used
//C- other than the proprietary Java implementation. If you modify this
//C- file, you may extend this exception to your version of the file, but
//C- you are not obligated to do so. If you do not wish to do so, delete
//C- this exception statement from your version.
//C- -------------------------------------------------------------------
//C- Developed by Bill C. Riemers, Foxtrot Technologies Inc. as work for
//C- hire under US copyright laws.
//C- -------------------------------------------------------------------
//
package com.lizardtech.djvu{
import java.io.*;
import java.util.cloner;


// Referenced classes of package com.lizardtech.javadjvu:
//            BitContext, DjVuStatic
public class ZPCodec
  extends DjVuObject
{
  //~ Static fields/initializers ---------------------------------------------

  /** DOCUMENT ME! */
  public static const ARRAYSIZE:int= 256;

  /** DOCUMENT ME! */
  protected static var FFZT:Array= new Array(ARRAYSIZE);

  
  private function construct() {
    for(var i:int= 0; i < ARRAYSIZE; i++)
    {
      FFZT[i] = 0;

      for(var j:int= i; (j & 0x80) > 0; j <<= 1)
      {
        FFZT[i]++;
      }
    }
  }

  //~ Instance fields --------------------------------------------------------

  private static var icount:int = 0;
  
  private static var lastContext:BitContext;

  /** DOCUMENT ME! */
  
  public static const defaultZtable:Array=
  [
    new ZPTable(32768, 0, 84, 145),
    new ZPTable(32768, 0, 3, 4),
    new ZPTable(32768, 0, 4, 3),
    new ZPTable(27581, 4261, 5, 1),
    new ZPTable(27581, 4261, 6, 2),
    new ZPTable(23877, 7976, 7, 3),
    new ZPTable(23877, 7976, 8, 4),
    new ZPTable(20921, 11219, 9, 5),
    new ZPTable(20921, 11219, 10, 6),
    new ZPTable(18451, 14051, 11, 7),
    new ZPTable(18451, 14051, 12, 8),
    new ZPTable(16341, 16524, 13, 9),
    new ZPTable(16341, 16524, 14, 10),
    new ZPTable(14513, 18685, 15, 11),
    new ZPTable(14513, 18685, 16, 12),
    new ZPTable(12917, 20573, 17, 13),
    new ZPTable(12917, 20573, 18, 14),
    new ZPTable(11517, 22224, 19, 15),
    new ZPTable(11517, 22224, 20, 16),
    new ZPTable(10277, 23665, 21, 17),
    new ZPTable(10277, 23665, 22, 18),
    new ZPTable(9131, 24923, 23, 19),
    new ZPTable(9131, 24923, 24, 20),
    new ZPTable(8071, 26021, 25, 21),
    new ZPTable(8071, 26021, 26, 22),
    new ZPTable(7099, 26978, 27, 23),
    new ZPTable(7099, 26978, 28, 24),
    new ZPTable(6213, 27810, 29, 25),
    new ZPTable(6213, 27810, 30, 26),
    new ZPTable(5411, 28532, 31, 27),
    new ZPTable(5411, 28532, 32, 28),
    new ZPTable(4691, 29158, 33, 29),
    new ZPTable(4691, 29158, 34, 30),
    new ZPTable(4047, 29700, 35, 31),
    new ZPTable(4047, 29700, 36, 32),
    new ZPTable(3477, 30166, 37, 33),
    new ZPTable(3477, 30166, 38, 34),
    new ZPTable(2973, 30568, 39, 35),
    new ZPTable(2973, 30568, 40, 36),
    new ZPTable(2531, 30914, 41, 37),
    new ZPTable(2531, 30914, 42, 38),
    new ZPTable(2145, 31210, 43, 39),
    new ZPTable(2145, 31210, 44, 40),
    new ZPTable(1809, 31463, 45, 41),
    new ZPTable(1809, 31463, 46, 42),
    new ZPTable(1521, 31678, 47, 43),
    new ZPTable(1521, 31678, 48, 44),
    new ZPTable(1273, 31861, 49, 45),
    new ZPTable(1273, 31861, 50, 46),
    new ZPTable(1061, 32015, 51, 47),
    new ZPTable(1061, 32015, 52, 48),
    new ZPTable(881, 32145, 53, 49),
    new ZPTable(881, 32145, 54, 50),
    new ZPTable(729, 32254, 55, 51),
    new ZPTable(729, 32254, 56, 52),
    new ZPTable(601, 32346, 57, 53),
    new ZPTable(601, 32346, 58, 54),
    new ZPTable(493, 32422, 59, 55),
    new ZPTable(493, 32422, 60, 56),
    new ZPTable(403, 32486, 61, 57),
    new ZPTable(403, 32486, 62, 58),
    new ZPTable(329, 32538, 63, 59),
    new ZPTable(329, 32538, 64, 60),
    new ZPTable(267, 32581, 65, 61),
    new ZPTable(267, 32581, 66, 62),
    new ZPTable(213, 32619, 67, 63),
    new ZPTable(213, 32619, 68, 64),
    new ZPTable(165, 32653, 69, 65),
    new ZPTable(165, 32653, 70, 66),
    new ZPTable(123, 32682, 71, 67),
    new ZPTable(123, 32682, 72, 68),
    new ZPTable(87, 32707, 73, 69),
    new ZPTable(87, 32707, 74, 70),
    new ZPTable(59, 32727, 75, 71),
    new ZPTable(59, 32727, 76, 72),
    new ZPTable(35, 32743, 77, 73),
    new ZPTable(35, 32743, 78, 74),
    new ZPTable(19, 32754, 79, 75),
    new ZPTable(19, 32754, 80, 76),
    new ZPTable(7, 32762, 81, 77),
    new ZPTable(7, 32762, 82, 78),
    new ZPTable(1, 32767, 81, 79),
    new ZPTable(1, 32767, 82, 80),
    new ZPTable(22165, 0, 9, 85),
    new ZPTable(9454, 0, 86, 226),
    new ZPTable(32768, 0, 5, 6),
    new ZPTable(3376, 0, 88, 176),
    new ZPTable(18458, 0, 89, 143),
    new ZPTable(1153, 0, 90, 138),
    new ZPTable(13689, 0, 91, 141),
    new ZPTable(378, 0, 92, 112),
    new ZPTable(9455, 0, 93, 135),
    new ZPTable(123, 0, 94, 104),
    new ZPTable(6520, 0, 95, 133),
    new ZPTable(40, 0, 96, 100),
    new ZPTable(4298, 0, 97, 129),
    new ZPTable(13, 0, 82, 98),
    new ZPTable(2909, 0, 99, 127),
    new ZPTable(52, 0, 76, 72),
    new ZPTable(1930, 0, 101, 125),
    new ZPTable(160, 0, 70, 102),
    new ZPTable(1295, 0, 103, 123),
    new ZPTable(279, 0, 66, 60),
    new ZPTable(856, 0, 105, 121),
    new ZPTable(490, 0, 106, 110),
    new ZPTable(564, 0, 107, 119),
    new ZPTable(324, 0, 66, 108),
    new ZPTable(371, 0, 109, 117),
    new ZPTable(564, 0, 60, 54),
    new ZPTable(245, 0, 111, 115),
    new ZPTable(851, 0, 56, 48),
    new ZPTable(161, 0, 69, 113),
    new ZPTable(1477, 0, 114, 134),
    new ZPTable(282, 0, 65, 59),
    new ZPTable(975, 0, 116, 132),
    new ZPTable(426, 0, 61, 55),
    new ZPTable(645, 0, 118, 130),
    new ZPTable(646, 0, 57, 51),
    new ZPTable(427, 0, 120, 128),
    new ZPTable(979, 0, 53, 47),
    new ZPTable(282, 0, 122, 126),
    new ZPTable(1477, 0, 49, 41),
    new ZPTable(186, 0, 124, 62),
    new ZPTable(2221, 0, 43, 37),
    new ZPTable(122, 0, 72, 66),
    new ZPTable(3276, 0, 39, 31),
    new ZPTable(491, 0, 60, 54),
    new ZPTable(4866, 0, 33, 25),
    new ZPTable(742, 0, 56, 50),
    new ZPTable(7041, 0, 29, 131),
    new ZPTable(1118, 0, 52, 46),
    new ZPTable(9455, 0, 23, 17),
    new ZPTable(1680, 0, 48, 40),
    new ZPTable(10341, 0, 23, 15),
    new ZPTable(2526, 0, 42, 136),
    new ZPTable(14727, 0, 137, 7),
    new ZPTable(3528, 0, 38, 32),
    new ZPTable(11417, 0, 21, 139),
    new ZPTable(4298, 0, 140, 172),
    new ZPTable(15199, 0, 15, 9),
    new ZPTable(2909, 0, 142, 170),
    new ZPTable(22165, 0, 9, 85),
    new ZPTable(1930, 0, 144, 168),
    new ZPTable(32768, 0, 141, 248),
    new ZPTable(1295, 0, 146, 166),
    new ZPTable(9454, 0, 147, 247),
    new ZPTable(856, 0, 148, 164),
    new ZPTable(3376, 0, 149, 197),
    new ZPTable(564, 0, 150, 162),
    new ZPTable(1153, 0, 151, 95),
    new ZPTable(371, 0, 152, 160),
    new ZPTable(378, 0, 153, 173),
    new ZPTable(245, 0, 154, 158),
    new ZPTable(123, 0, 155, 165),
    new ZPTable(161, 0, 70, 156),
    new ZPTable(40, 0, 157, 161),
    new ZPTable(282, 0, 66, 60),
    new ZPTable(13, 0, 81, 159),
    new ZPTable(426, 0, 62, 56),
    new ZPTable(52, 0, 75, 71),
    new ZPTable(646, 0, 58, 52),
    new ZPTable(160, 0, 69, 163),
    new ZPTable(979, 0, 54, 48),
    new ZPTable(279, 0, 65, 59),
    new ZPTable(1477, 0, 50, 42),
    new ZPTable(490, 0, 167, 171),
    new ZPTable(2221, 0, 44, 38),
    new ZPTable(324, 0, 65, 169),
    new ZPTable(3276, 0, 40, 32),
    new ZPTable(564, 0, 59, 53),
    new ZPTable(4866, 0, 34, 26),
    new ZPTable(851, 0, 55, 47),
    new ZPTable(7041, 0, 30, 174),
    new ZPTable(1477, 0, 175, 193),
    new ZPTable(9455, 0, 24, 18),
    new ZPTable(975, 0, 177, 191),
    new ZPTable(11124, 0, 178, 222),
    new ZPTable(645, 0, 179, 189),
    new ZPTable(8221, 0, 180, 218),
    new ZPTable(427, 0, 181, 187),
    new ZPTable(5909, 0, 182, 216),
    new ZPTable(282, 0, 183, 185),
    new ZPTable(4023, 0, 184, 214),
    new ZPTable(186, 0, 69, 61),
    new ZPTable(2663, 0, 186, 212),
    new ZPTable(491, 0, 59, 53),
    new ZPTable(1767, 0, 188, 210),
    new ZPTable(742, 0, 55, 49),
    new ZPTable(1174, 0, 190, 208),
    new ZPTable(1118, 0, 51, 45),
    new ZPTable(781, 0, 192, 206),
    new ZPTable(1680, 0, 47, 39),
    new ZPTable(518, 0, 194, 204),
    new ZPTable(2526, 0, 41, 195),
    new ZPTable(341, 0, 196, 202),
    new ZPTable(3528, 0, 37, 31),
    new ZPTable(225, 0, 198, 200),
    new ZPTable(11124, 0, 199, 243),
    new ZPTable(148, 0, 72, 64),
    new ZPTable(8221, 0, 201, 239),
    new ZPTable(392, 0, 62, 56),
    new ZPTable(5909, 0, 203, 237),
    new ZPTable(594, 0, 58, 52),
    new ZPTable(4023, 0, 205, 235),
    new ZPTable(899, 0, 54, 48),
    new ZPTable(2663, 0, 207, 233),
    new ZPTable(1351, 0, 50, 44),
    new ZPTable(1767, 0, 209, 231),
    new ZPTable(2018, 0, 46, 38),
    new ZPTable(1174, 0, 211, 229),
    new ZPTable(3008, 0, 40, 34),
    new ZPTable(781, 0, 213, 227),
    new ZPTable(4472, 0, 36, 28),
    new ZPTable(518, 0, 215, 225),
    new ZPTable(6618, 0, 30, 22),
    new ZPTable(341, 0, 217, 223),
    new ZPTable(9455, 0, 26, 16),
    new ZPTable(225, 0, 219, 221),
    new ZPTable(12814, 0, 20, 220),
    new ZPTable(148, 0, 71, 63),
    new ZPTable(17194, 0, 14, 8),
    new ZPTable(392, 0, 61, 55),
    new ZPTable(17533, 0, 14, 224),
    new ZPTable(594, 0, 57, 51),
    new ZPTable(24270, 0, 8, 2),
    new ZPTable(899, 0, 53, 47),
    new ZPTable(32768, 0, 228, 87),
    new ZPTable(1351, 0, 49, 43),
    new ZPTable(18458, 0, 230, 246),
    new ZPTable(2018, 0, 45, 37),
    new ZPTable(13689, 0, 232, 244),
    new ZPTable(3008, 0, 39, 33),
    new ZPTable(9455, 0, 234, 238),
    new ZPTable(4472, 0, 35, 27),
    new ZPTable(6520, 0, 138, 236),
    new ZPTable(6618, 0, 29, 21),
    new ZPTable(10341, 0, 24, 16),
    new ZPTable(9455, 0, 25, 15),
    new ZPTable(14727, 0, 240, 8),
    new ZPTable(12814, 0, 19, 241),
    new ZPTable(11417, 0, 22, 242),
    new ZPTable(17194, 0, 13, 7),
    new ZPTable(15199, 0, 16, 10),
    new ZPTable(17533, 0, 13, 245),
    new ZPTable(22165, 0, 10, 2),
    new ZPTable(24270, 0, 7, 1),
    new ZPTable(32768, 0, 244, 83),
    new ZPTable(32768, 0, 249, 250),
    new ZPTable(22165, 0, 10, 2),
    new ZPTable(18458, 0, 89, 143),
    new ZPTable(18458, 0, 230, 246),
    new ZPTable(0, 0, 0, 0),
    new ZPTable(0, 0, 0, 0),
    new ZPTable(0, 0, 0, 0),
    new ZPTable(0, 0, 0, 0),
    new ZPTable(0, 0, 0, 0)
  ];
 /*
  [
    new ZPTable(32768, 0, new Number(84), new Number(145)),
    new ZPTable(32768, 0, new Number(3), new Number(4)),
    new ZPTable(32768, 0, new Number(4), new Number(3)),
    new ZPTable(27581, 4261, new Number(5), new Number(1)),
    new ZPTable(27581, 4261, new Number(6), new Number(2)),
    new ZPTable(23877, 7976, new Number(7), new Number(3)),
    new ZPTable(23877, 7976, new Number(8), new Number(4)),
    new ZPTable(20921, 11219, new Number(9), new Number(5)),
    new ZPTable(20921, 11219, new Number(10), new Number(6)),
    new ZPTable(18451, 14051, new Number(11), new Number(7)),
    new ZPTable(18451, 14051, new Number(12), new Number(8)),
    new ZPTable(16341, 16524, new Number(13), new Number(9)),
    new ZPTable(16341, 16524, new Number(14), new Number(10)),
    new ZPTable(14513, 18685, new Number(15), new Number(11)),
    new ZPTable(14513, 18685, new Number(16), new Number(12)),
    new ZPTable(12917, 20573, new Number(17), new Number(13)),
    new ZPTable(12917, 20573, new Number(18), new Number(14)),
    new ZPTable(11517, 22224, new Number(19), new Number(15)),
    new ZPTable(11517, 22224, new Number(20), new Number(16)),
    new ZPTable(10277, 23665, new Number(21), new Number(17)),
    new ZPTable(10277, 23665, new Number(22), new Number(18)),
    new ZPTable(9131, 24923, new Number(23), new Number(19)),
    new ZPTable(9131, 24923, new Number(24), new Number(20)),
    new ZPTable(8071, 26021, new Number(25), new Number(21)),
    new ZPTable(8071, 26021, new Number(26), new Number(22)),
    new ZPTable(7099, 26978, new Number(27), new Number(23)),
    new ZPTable(7099, 26978, new Number(28), new Number(24)),
    new ZPTable(6213, 27810, new Number(29), new Number(25)),
    new ZPTable(6213, 27810, new Number(30), new Number(26)),
    new ZPTable(5411, 28532, new Number(31), new Number(27)),
    new ZPTable(5411, 28532, new Number(32), new Number(28)),
    new ZPTable(4691, 29158, new Number(33), new Number(29)),
    new ZPTable(4691, 29158, new Number(34), new Number(30)),
    new ZPTable(4047, 29700, new Number(35), new Number(31)),
    new ZPTable(4047, 29700, new Number(36), new Number(32)),
    new ZPTable(3477, 30166, new Number(37), new Number(33)),
    new ZPTable(3477, 30166, new Number(38), new Number(34)),
    new ZPTable(2973, 30568, new Number(39), new Number(35)),
    new ZPTable(2973, 30568, new Number(40), new Number(36)),
    new ZPTable(2531, 30914, new Number(41), new Number(37)),
    new ZPTable(2531, 30914, new Number(42), new Number(38)),
    new ZPTable(2145, 31210, new Number(43), new Number(39)),
    new ZPTable(2145, 31210, new Number(44), new Number(40)),
    new ZPTable(1809, 31463, new Number(45), new Number(41)),
    new ZPTable(1809, 31463, new Number(46), new Number(42)),
    new ZPTable(1521, 31678, new Number(47), new Number(43)),
    new ZPTable(1521, 31678, new Number(48), new Number(44)),
    new ZPTable(1273, 31861, new Number(49), new Number(45)),
    new ZPTable(1273, 31861, new Number(50), new Number(46)),
    new ZPTable(1061, 32015, new Number(51), new Number(47)),
    new ZPTable(1061, 32015, new Number(52), new Number(48)),
    new ZPTable(881, 32145, new Number(53), new Number(49)),
    new ZPTable(881, 32145, new Number(54), new Number(50)),
    new ZPTable(729, 32254, new Number(55), new Number(51)),
    new ZPTable(729, 32254, new Number(56), new Number(52)),
    new ZPTable(601, 32346, new Number(57), new Number(53)),
    new ZPTable(601, 32346, new Number(58), new Number(54)),
    new ZPTable(493, 32422, new Number(59), new Number(55)),
    new ZPTable(493, 32422, new Number(60), new Number(56)),
    new ZPTable(403, 32486, new Number(61), new Number(57)),
    new ZPTable(403, 32486, new Number(62), new Number(58)),
    new ZPTable(329, 32538, new Number(63), new Number(59)),
    new ZPTable(329, 32538, new Number(64), new Number(60)),
    new ZPTable(267, 32581, new Number(65), new Number(61)),
    new ZPTable(267, 32581, new Number(66), new Number(62)),
    new ZPTable(213, 32619, new Number(67), new Number(63)),
    new ZPTable(213, 32619, new Number(68), new Number(64)),
    new ZPTable(165, 32653, new Number(69), new Number(65)),
    new ZPTable(165, 32653, new Number(70), new Number(66)),
    new ZPTable(123, 32682, new Number(71), new Number(67)),
    new ZPTable(123, 32682, new Number(72), new Number(68)),
    new ZPTable(87, 32707, new Number(73), new Number(69)),
    new ZPTable(87, 32707, new Number(74), new Number(70)),
    new ZPTable(59, 32727, new Number(75), new Number(71)),
    new ZPTable(59, 32727, new Number(76), new Number(72)),
    new ZPTable(35, 32743, new Number(77), new Number(73)),
    new ZPTable(35, 32743, new Number(78), new Number(74)),
    new ZPTable(19, 32754, new Number(79), new Number(75)),
    new ZPTable(19, 32754, new Number(80), new Number(76)),
    new ZPTable(7, 32762, new Number(81), new Number(77)),
    new ZPTable(7, 32762, new Number(82), new Number(78)),
    new ZPTable(1, 32767, new Number(81), new Number(79)),
    new ZPTable(1, 32767, new Number(82), new Number(80)),
    new ZPTable(22165, 0, new Number(9), new Number(85)),
    new ZPTable(9454, 0, new Number(86), new Number(226)),
    new ZPTable(32768, 0, new Number(5), new Number(6)),
    new ZPTable(3376, 0, new Number(88), new Number(176)),
    new ZPTable(18458, 0, new Number(89), new Number(143)),
    new ZPTable(1153, 0, new Number(90), new Number(138)),
    new ZPTable(13689, 0, new Number(91), new Number(141)),
    new ZPTable(378, 0, new Number(92), new Number(112)),
    new ZPTable(9455, 0, new Number(93), new Number(135)),
    new ZPTable(123, 0, new Number(94), new Number(104)),
    new ZPTable(6520, 0, new Number(95), new Number(133)),
    new ZPTable(40, 0, new Number(96), new Number(100)),
    new ZPTable(4298, 0, new Number(97), new Number(129)),
    new ZPTable(13, 0, new Number(82), new Number(98)),
    new ZPTable(2909, 0, new Number(99), new Number(127)),
    new ZPTable(52, 0, new Number(76), new Number(72)),
    new ZPTable(1930, 0, new Number(101), new Number(125)),
    new ZPTable(160, 0, new Number(70), new Number(102)),
    new ZPTable(1295, 0, new Number(103), new Number(123)),
    new ZPTable(279, 0, new Number(66), new Number(60)),
    new ZPTable(856, 0, new Number(105), new Number(121)),
    new ZPTable(490, 0, new Number(106), new Number(110)),
    new ZPTable(564, 0, new Number(107), new Number(119)),
    new ZPTable(324, 0, new Number(66), new Number(108)),
    new ZPTable(371, 0, new Number(109), new Number(117)),
    new ZPTable(564, 0, new Number(60), new Number(54)),
    new ZPTable(245, 0, new Number(111), new Number(115)),
    new ZPTable(851, 0, new Number(56), new Number(48)),
    new ZPTable(161, 0, new Number(69), new Number(113)),
    new ZPTable(1477, 0, new Number(114), new Number(134)),
    new ZPTable(282, 0, new Number(65), new Number(59)),
    new ZPTable(975, 0, new Number(116), new Number(132)),
    new ZPTable(426, 0, new Number(61), new Number(55)),
    new ZPTable(645, 0, new Number(118), new Number(130)),
    new ZPTable(646, 0, new Number(57), new Number(51)),
    new ZPTable(427, 0, new Number(120), new Number(128)),
    new ZPTable(979, 0, new Number(53), new Number(47)),
    new ZPTable(282, 0, new Number(122), new Number(126)),
    new ZPTable(1477, 0, new Number(49), new Number(41)),
    new ZPTable(186, 0, new Number(124), new Number(62)),
    new ZPTable(2221, 0, new Number(43), new Number(37)),
    new ZPTable(122, 0, new Number(72), new Number(66)),
    new ZPTable(3276, 0, new Number(39), new Number(31)),
    new ZPTable(491, 0, new Number(60), new Number(54)),
    new ZPTable(4866, 0, new Number(33), new Number(25)),
    new ZPTable(742, 0, new Number(56), new Number(50)),
    new ZPTable(7041, 0, new Number(29), new Number(131)),
    new ZPTable(1118, 0, new Number(52), new Number(46)),
    new ZPTable(9455, 0, new Number(23), new Number(17)),
    new ZPTable(1680, 0, new Number(48), new Number(40)),
    new ZPTable(10341, 0, new Number(23), new Number(15)),
    new ZPTable(2526, 0, new Number(42), new Number(136)),
    new ZPTable(14727, 0, new Number(137), new Number(7)),
    new ZPTable(3528, 0, new Number(38), new Number(32)),
    new ZPTable(11417, 0, new Number(21), new Number(139)),
    new ZPTable(4298, 0, new Number(140), new Number(172)),
    new ZPTable(15199, 0, new Number(15), new Number(9)),
    new ZPTable(2909, 0, new Number(142), new Number(170)),
    new ZPTable(22165, 0, new Number(9), new Number(85)),
    new ZPTable(1930, 0, new Number(144), new Number(168)),
    new ZPTable(32768, 0, new Number(141), new Number(248)),
    new ZPTable(1295, 0, new Number(146), new Number(166)),
    new ZPTable(9454, 0, new Number(147), new Number(247)),
    new ZPTable(856, 0, new Number(148), new Number(164)),
    new ZPTable(3376, 0, new Number(149), new Number(197)),
    new ZPTable(564, 0, new Number(150), new Number(162)),
    new ZPTable(1153, 0, new Number(151), new Number(95)),
    new ZPTable(371, 0, new Number(152), new Number(160)),
    new ZPTable(378, 0, new Number(153), new Number(173)),
    new ZPTable(245, 0, new Number(154), new Number(158)),
    new ZPTable(123, 0, new Number(155), new Number(165)),
    new ZPTable(161, 0, new Number(70), new Number(156)),
    new ZPTable(40, 0, new Number(157), new Number(161)),
    new ZPTable(282, 0, new Number(66), new Number(60)),
    new ZPTable(13, 0, new Number(81), new Number(159)),
    new ZPTable(426, 0, new Number(62), new Number(56)),
    new ZPTable(52, 0, new Number(75), new Number(71)),
    new ZPTable(646, 0, new Number(58), new Number(52)),
    new ZPTable(160, 0, new Number(69), new Number(163)),
    new ZPTable(979, 0, new Number(54), new Number(48)),
    new ZPTable(279, 0, new Number(65), new Number(59)),
    new ZPTable(1477, 0, new Number(50), new Number(42)),
    new ZPTable(490, 0, new Number(167), new Number(171)),
    new ZPTable(2221, 0, new Number(44), new Number(38)),
    new ZPTable(324, 0, new Number(65), new Number(169)),
    new ZPTable(3276, 0, new Number(40), new Number(32)),
    new ZPTable(564, 0, new Number(59), new Number(53)),
    new ZPTable(4866, 0, new Number(34), new Number(26)),
    new ZPTable(851, 0, new Number(55), new Number(47)),
    new ZPTable(7041, 0, new Number(30), new Number(174)),
    new ZPTable(1477, 0, new Number(175), new Number(193)),
    new ZPTable(9455, 0, new Number(24), new Number(18)),
    new ZPTable(975, 0, new Number(177), new Number(191)),
    new ZPTable(11124, 0, new Number(178), new Number(222)),
    new ZPTable(645, 0, new Number(179), new Number(189)),
    new ZPTable(8221, 0, new Number(180), new Number(218)),
    new ZPTable(427, 0, new Number(181), new Number(187)),
    new ZPTable(5909, 0, new Number(182), new Number(216)),
    new ZPTable(282, 0, new Number(183), new Number(185)),
    new ZPTable(4023, 0, new Number(184), new Number(214)),
    new ZPTable(186, 0, new Number(69), new Number(61)),
    new ZPTable(2663, 0, new Number(186), new Number(212)),
    new ZPTable(491, 0, new Number(59), new Number(53)),
    new ZPTable(1767, 0, new Number(188), new Number(210)),
    new ZPTable(742, 0, new Number(55), new Number(49)),
    new ZPTable(1174, 0, new Number(190), new Number(208)),
    new ZPTable(1118, 0, new Number(51), new Number(45)),
    new ZPTable(781, 0, new Number(192), new Number(206)),
    new ZPTable(1680, 0, new Number(47), new Number(39)),
    new ZPTable(518, 0, new Number(194), new Number(204)),
    new ZPTable(2526, 0, new Number(41), new Number(195)),
    new ZPTable(341, 0, new Number(196), new Number(202)),
    new ZPTable(3528, 0, new Number(37), new Number(31)),
    new ZPTable(225, 0, new Number(198), new Number(200)),
    new ZPTable(11124, 0, new Number(199), new Number(243)),
    new ZPTable(148, 0, new Number(72), new Number(64)),
    new ZPTable(8221, 0, new Number(201), new Number(239)),
    new ZPTable(392, 0, new Number(62), new Number(56)),
    new ZPTable(5909, 0, new Number(203), new Number(237)),
    new ZPTable(594, 0, new Number(58), new Number(52)),
    new ZPTable(4023, 0, new Number(205), new Number(235)),
    new ZPTable(899, 0, new Number(54), new Number(48)),
    new ZPTable(2663, 0, new Number(207), new Number(233)),
    new ZPTable(1351, 0, new Number(50), new Number(44)),
    new ZPTable(1767, 0, new Number(209), new Number(231)),
    new ZPTable(2018, 0, new Number(46), new Number(38)),
    new ZPTable(1174, 0, new Number(211), new Number(229)),
    new ZPTable(3008, 0, new Number(40), new Number(34)),
    new ZPTable(781, 0, new Number(213), new Number(227)),
    new ZPTable(4472, 0, new Number(36), new Number(28)),
    new ZPTable(518, 0, new Number(215), new Number(225)),
    new ZPTable(6618, 0, new Number(30), new Number(22)),
    new ZPTable(341, 0, new Number(217), new Number(223)),
    new ZPTable(9455, 0, new Number(26), new Number(16)),
    new ZPTable(225, 0, new Number(219), new Number(221)),
    new ZPTable(12814, 0, new Number(20), new Number(220)),
    new ZPTable(148, 0, new Number(71), new Number(63)),
    new ZPTable(17194, 0, new Number(14), new Number(8)),
    new ZPTable(392, 0, new Number(61), new Number(55)),
    new ZPTable(17533, 0, new Number(14), new Number(224)),
    new ZPTable(594, 0, new Number(57), new Number(51)),
    new ZPTable(24270, 0, new Number(8), new Number(2)),
    new ZPTable(899, 0, new Number(53), new Number(47)),
    new ZPTable(32768, 0, new Number(228), new Number(87)),
    new ZPTable(1351, 0, new Number(49), new Number(43)),
    new ZPTable(18458, 0, new Number(230), new Number(246)),
    new ZPTable(2018, 0, new Number(45), new Number(37)),
    new ZPTable(13689, 0, new Number(232), new Number(244)),
    new ZPTable(3008, 0, new Number(39), new Number(33)),
    new ZPTable(9455, 0, new Number(234), new Number(238)),
    new ZPTable(4472, 0, new Number(35), new Number(27)),
    new ZPTable(6520, 0, new Number(138), new Number(236)),
    new ZPTable(6618, 0, new Number(29), new Number(21)),
    new ZPTable(10341, 0, new Number(24), new Number(16)),
    new ZPTable(9455, 0, new Number(25), new Number(15)),
    new ZPTable(14727, 0, new Number(240), new Number(8)),
    new ZPTable(12814, 0, new Number(19), new Number(241)),
    new ZPTable(11417, 0, new Number(22), new Number(242)),
    new ZPTable(17194, 0, new Number(13), new Number(7)),
    new ZPTable(15199, 0, new Number(16), new Number(10)),
    new ZPTable(17533, 0, new Number(13), new Number(245)),
    new ZPTable(22165, 0, new Number(10), new Number(2)),
    new ZPTable(24270, 0, new Number(7), new Number(1)),
    new ZPTable(32768, 0, new Number(244), new Number(83)),
    new ZPTable(32768, 0, new Number(249), new Number(250)),
    new ZPTable(22165, 0, new Number(10), new Number(2)),
    new ZPTable(18458, 0, new Number(89), new Number(143)),
    new ZPTable(18458, 0, new Number(230), new Number(246)),
    new ZPTable(0, 0, new Number(0), new Number(0)),
    new ZPTable(0, 0, new Number(0), new Number(0)),
    new ZPTable(0, 0, new Number(0), new Number(0)),
    new ZPTable(0, 0, new Number(0), new Number(0)),
    new ZPTable(0, 0, new Number(0), new Number(0))
  ];
  */

  /** DOCUMENT ME! */
  public var bitcount:int;

  /** DOCUMENT ME! */
  protected var dn:Array= new Array(ARRAYSIZE); //BitContext[ARRAYSIZE];

  /** DOCUMENT ME! */
  protected var ffzt:Array;

  /** DOCUMENT ME! */
  protected var mArray:Array= new Array(ARRAYSIZE); //int[ARRAYSIZE];

  /** DOCUMENT ME! */
  protected var pArray:Array= new Array(ARRAYSIZE); //int[ARRAYSIZE];

  /** DOCUMENT ME! */
  protected var up:Array= new Array(ARRAYSIZE); //BitContext[ARRAYSIZE];

  /** DOCUMENT ME! */
  protected var aValue:int;
  private var ibs:IFFChunk;
  private var obs:OutputStream;
  private var buffer:Number;
  private var code:Number;
  private var fence:Number;
  private var nrun:Number;
  private var subend:Number;
  private var delay:int;
  private var scount:uint;
  private var zByte:uint;

  //~ Constructors -----------------------------------------------------------

  /**
   * Creates a new ZPCodec object.
   */
  public function ZPCodec(ibs:*=null)
  {
  	construct();
    //ffzt = new Array(FFZT.length);
    //System.arraycopy(FFZT, 0, ffzt, 0, ffzt.length);
    ffzt = java.util.cloner.clone(FFZT);

    for(var i:int= 0; i < ARRAYSIZE; i++)
    {
      up[i]   = new BitContext();
      dn[i]   = new BitContext();
    }
    if(ibs) { init(ibs); }
  }

  /**
   * Creates a new ZPCodec object.
   *
   * @param ibs DOCUMENT ME!
   *
   * @ DOCUMENT ME!
   */
  //public function ZPCodec(ibs:InputStream) {
  //  this();
  //  init(ibs);
  //}

  //~ Methods ----------------------------------------------------------------

  /**
   * Creates an instance of ZPCodec with the options interherited from the
   * specified reference.
   *
   * @param ref Object to interherit DjVuOptions from.
   *
   * @return a new instance of ZPCodec.
   */
  public static function createZPCodec(ref:DjVuInterface):ZPCodec{
    var options:DjVuOptions= ref.getDjVuOptions();

    return create(
      options,
      options.getZPCodecClass(),
      "com.lizardtech.djvu.ZPCodec") as ZPCodec;
  }

  /**
   * DOCUMENT ME!
   *
   * @return DOCUMENT ME!
   *
   * @ DOCUMENT ME!
   */
  public function IWdecoder():int
  {
    return decode_sub_simple(0, 0x8000 + ((aValue + aValue + aValue) >> 3));
  }

  /**
   * DOCUMENT ME!
   *
   * @param ctx DOCUMENT ME!
   * @param z DOCUMENT ME!
   *
   * @return DOCUMENT ME!
   *
   * @ DOCUMENT ME!
   */
  public function decode_sub(
    ctx:BitContext,
    z:int):int
  {
    var bit:int= ctx.bit & 1;
    var d:int= 24576 + ((z + aValue) >> 2);

    if(z > d)
    {
      z = d;
    }

	//trace("z: " + z + " > " + code + " " + ctx.bit + " " + fence);
    if(z > code)
    {
      z = 0x10000- z;
      aValue += z;
      code += z;
      //ctx.set(0xff & (dn[0xff & ctx.bit] as BitContext).bit);
      ctx.set((dn[ctx.bit] as BitContext).bit);

      var shift:int= ffz(aValue);
      scount -= shift;
      aValue   = 0xffff & (aValue << shift);
      code =
        0xffff & ((code << shift) | (buffer >> scount) & ((1 << shift) - 1));

      if(scount < 16)
      {
      	//trace("load1: " + code);
        preload();
      }

      fence    = code;

      if(code >= 32768)
      {
        fence = 32767;
      }

      return bit ^ 1;
    }

    if((aValue) >= (mArray[ctx.bit]))
    {
      //ctx.set(0xff & (up[0xff & ctx.bit] as BitContext).bit);
      ctx.set((up[ctx.bit] as BitContext).bit);
    }

    scount--;
    aValue   = 0xffff & (z << 1);
    code     = 0xffff & ((code << 1) | ((buffer >> scount) & 1));

    if(scount < 16)
    {
      //trace("load2: " + code);
      preload();
    }

    fence = code;

    if(code >= 32768)
    {
      fence = 32767;
    }

    return bit;
  }

  /**
   * DOCUMENT ME!
   *
   * @param mps DOCUMENT ME!
   * @param z DOCUMENT ME!
   *
   * @return DOCUMENT ME!
   *
   * @ DOCUMENT ME!
   */
  public function decode_sub_nolearn(
    mps:int,
    z:int):int
  {
    var d:int= 24576+ ((z + aValue) >> 2);

    if(z > d)
    {
      z = d;
    }

    if(z > code)
    {
      z = 0x10000- z;
      aValue += z;
      code += z;

      var shift:int= ffz(aValue);
      scount -= shift;
      aValue   = 0xffff & (aValue << shift);
      code =
        0xffff & ((code << shift) | ((buffer >> scount) & ((1 << shift) - 1)));

      if(scount < 16)
      {
        preload();
      }

      fence    = code;

      if(code >= 32768)
      {
        fence = 32767;
      }

      return mps ^ 1;
    }

    scount--;
    aValue   = 0xffff & (z << 1);
    code     = 0xffff & ((code << 1) | ((buffer >> scount) & 1));

    if(scount < 16)
    {
      preload();
    }

    fence = code;

    if(code >= 32768)
    {
      fence = 32767;
    }

    return mps;
  }

  /**
   * DOCUMENT ME!
   *
   * @param mps DOCUMENT ME!
   * @param z DOCUMENT ME!
   *
   * @return DOCUMENT ME!
   *
   * @ DOCUMENT ME!
   */
  public function decode_sub_simple(
    mps:int,
    z:int):int
  {
    if(z > code)
    {
      z = 0x10000- z;
      aValue += z;
      code += z;

      var shift:int= ffz(aValue);
      scount -= shift;
      aValue   = 0xffff & (aValue << shift);
      code =
        0xffff & ((code << shift) | ((buffer >> scount) & ((1 << shift) - 1)));

      if(scount < 16)
      {
        preload();
      }

      fence    = code;

      if(code >= 32768)
      {
        fence = 32767;
      }

      return mps ^ 1;
    }

    scount--;
    aValue   = 0xffff & (z << 1);
    code     = 0xffff & ((code << 1) | ((buffer >> scount) & 1));

    if(scount < 16)
    {
      preload();
    }

    fence = code;

    if(code >= 32768)
    {
      fence = 32767;
    }

    return mps;
  }

  /**
   * DOCUMENT ME!
   *
   * @return DOCUMENT ME!
   *
   * @ DOCUMENT ME!
   */
  public function decoder(ctx:BitContext=null):int
  {
  	if(ctx is BitContext) { 
  		return decoderB(ctx);
     } else { 
     	return decode_sub_simple(0, 0x8000+ (aValue >> 1)); 
     }
  }

  /**
   * DOCUMENT ME!
   *
   * @param ctx DOCUMENT ME!
   *
   * @return DOCUMENT ME!
   *
   * @ DOCUMENT ME!
   */
  public function decoderB(ctx:BitContext):int
  {
  	
  	
  	/*
  	if((ctx.bit == 0)  && (lastContext != null) && (icount > 0) && (icount >= aValue)) {   
		//ctx = lastContext;
		trace("stop: " + aValue + " " + icount);
	}
	*/
	
  	
    var ictx:int= 0xff & ctx.bit;
    var z:int= aValue + pArray[ictx];

    icount++;

	//trace("f["+icount+"]: " + z + " <= " + fence + " " + (z <= fence) + " " + ictx + " " + pArray[ictx] + (ictx & 1));
	
	//if(z == fence) { 
	//	trace("here2");
	//}
	
    if(z <= fence)
    {
      aValue = z;
	  lastContext = ctx;

      return ictx & 1;
    }
    else
    {
       icount = 0;
      return decode_sub(ctx, z);
    }
  }

  /**
   * DOCUMENT ME!
   *
   * @param x DOCUMENT ME!
   *
   * @return DOCUMENT ME!
   */
  public function ffz(x:int):int{
    return ((0xffffffff & x) < 65280)
    ? ffzt[0xff & (x >> 8)]
    : (ffzt[0xff & x] + 8);
  }

  /**
   * DOCUMENT ME!
   *
   * @param ibs DOCUMENT ME!
   *
   * @return DOCUMENT ME!
   *
   * @ DOCUMENT ME!
   */
  public function init(ibs:IFFChunk):ZPCodec
  {
    this.ibs = ibs;
    dinit();

    return this;
  }

  /**
   * DOCUMENT ME!
   *
   * @param table DOCUMENT ME!
   */
  public function newZPTable(table:Array):void{
    for(var i:int= 0; i < ARRAYSIZE; i++)
    {
      pArray[i]   = table[i].pValue;
      mArray[i]   = table[i].mValue;
      (up[i] as BitContext).set(table[i].up);
      (dn[i] as BitContext).set(table[i].dn);
    }
  }

  /**
   * DOCUMENT ME!
   *
   * @ DOCUMENT ME!
   */
  public function preload():void
  {
  	
    for(; scount <= 24; scount += 8)
    {
      zByte   = -1;

      //trace("ibs.pos: " + ibs.position);
      zByte = ibs.read();
   	  

      if(zByte == -1)
      {
        zByte = 255;
		trace("ipos: ("+delay+") " + ibs.position);

        if(--delay < 1)
        {
          throw new IOException("EOF");
        }
      }

      buffer = (buffer << 8) | zByte;
      
      lastContext = null;
      
      //trace("buffer: " + buffer);
    }
  }

  function dinit():void
  {
    aValue = 0;
    newZPTable(defaultZtable);
    code = 0xff00;

    try
    {
      code &= (ibs.read() << 8);
      zByte = 0xffff & int((0xff & ibs.read()));
    }
    catch(exp:*)
    {
      zByte = 255;
    }

    code |= zByte;
    delay    = 25;
    scount   = 0;
    preload();
    fence = code;

    if(code >= 32768)
    {
      fence = 32767;
    }
  }
}}